package org.massi.imslp.query;


import org.apache.commons.lang.StringUtils;
import org.massi.imslp.query.WorkInfo.Builder;


public enum TemplateParameter
{
	/**
	 * key of the piece
	 */
	Key()
	{

		@Override
		public void build(final Builder builder, final String value)
		{
			// workaround for a template issue
			final String normalized = StringUtils.replace(value, "(TEMPLATE)", " flat");
			builder.key(normalized);
		}
	},
	/**
	 * opus number
	 */
	OpusNumber("Opus/Catalogue Number")
	{

		@Override
		public void build(final Builder builder, final String value)
		{
			builder.opusNumber(value);
		}
	},
	/**
	 * when the piece has been composed
	 */
	DateOfComposition("Year/Date of Composition")
	{
		@Override
		public void build(final Builder builder, final String value)
		{
			builder.dateOfComposition(value);
		}
	},
	/**
	 * instruments
	 */
	Score("Instrumentation")
	{
		@Override
		public void build(final Builder builder, final String value)
		{
			builder.score(value);
		}
	},
	/**
	 * style (baroque, classical..)
	 */
	Style("Piece Style")
	{
		@Override
		public void build(final Builder builder, final String value)
		{
			builder.style(value);
		}
	},
	/**
	 * when the piece has been first published
	 */
	DateOfPublication("Year of First Publication")
	{
		@Override
		public void build(final Builder builder, final String value)
		{
			builder.dateOfPublication(value);
		}
	},
	/**
	 * piece dedication
	 */
	Dedication("Dedication")
	{
		@Override
		public void build(final Builder builder, final String value)
		{
			builder.dedication(value);
		}
	},
	/**
	 * work title
	 */
	WorkTitle("Work Title")
	{
		@Override
		public void build(final Builder builder, final String value)
		{
			builder.title(value);
		}
	},
	/**
	 * any comments
	 */
	Comments("*****COMMENTS*****")
	{
		@Override
		public void build(final Builder builder, final String value)
		{
			builder.comments(value);
		}
	};

	/**
	 * holds the key for the template parameter in the Wiki page
	 */
	private final String name;


	/**
	 * Creates a new instance with the string representing the parameter name
	 * 
	 * @param name may be null, in this case the {@link #name()} implementation will be used (name
	 *            of the enum)
	 */
	private TemplateParameter(final String name)
	{
		this.name = name != null ? name : name();
	}


	/**
	 * Empty constructor using the enum {@link #name()} method
	 */
	private TemplateParameter()
	{
		this.name = name();
	}


	/**
	 * Return a {@link TemplateParameter} instance if the parameter name matches one of the relevant
	 * ones
	 * 
	 * @param name name of the parameter
	 * @return the {@link TemplateParameter} instance or null if the parameter name is not relevant.
	 *         Return null if the given parameter name is null
	 */
	public static TemplateParameter fromName(final String name)
	{
		for (final TemplateParameter parameter : TemplateParameter.values())
		{
			if (parameter.name.equals(name))
			{
				return parameter;
			}
		}
		return null;
	}


	/**
	 * Use the provided builder to set the relevant attribute in the work info
	 * 
	 * @param builder
	 * @param value
	 */
	public abstract void build(final WorkInfo.Builder builder, final String value);
}
